package statemachine;

import lombok.extern.slf4j.Slf4j;
import org.squirrelframework.foundation.fsm.*;
import org.squirrelframework.foundation.fsm.annotation.*;
import org.squirrelframework.foundation.fsm.impl.AbstractStateMachine;

/**
 * @Author zhangtao
 * @create 2023/8/9 15:08
 */
@States({
        @State(name = "A", entryCallMethod = "ontoA", exitCallMethod = "exitA")
})
@Transitions({
        @Transit(from = "A", to = "B", on = "GoToB", callMethod = "fromAGoToB"),
        @Transit(from = "B", to = "C", on = "GoToC", callMethod = "fromBGoToC")
})
@StateMachineParameters(stateType = String.class, eventType = String.class, contextType = Integer.class)
@Slf4j
public class MyAnnotationStateMachine extends AbstractStateMachine<MyAnnotationStateMachine, String, String, Integer> {

    protected void fromAGoToB(String from, String to, String event, Integer context) {
        log.info("fromAGoToB from '" + from + "' to '" + to + "' on event '" + event +
                "' with context '" + context + "'.");
    }

    protected void fromBGoToC(String from, String to, String event, Integer context) {
        log.info("fromBGoToC from '" + from + "' to '" + to + "' on event '" + event +
                "' with context '" + context + "'.");
    }

    protected void ontoA(String from, String to, String event, Integer context) {
        log.info("ontoA from '" + from + "' to '" + to + "' on event '" + event +
                "' with context '" + context + "'.");
    }

    protected void exitA(String from, String to, String event, Integer context) {
        log.info("exitA from '" + from + "' to '" + to + "' on event '" + event +
                "' with context '" + context + "'.");
    }

    @Override
    protected void afterTransitionCausedException(String from, String to, String event, Integer context) {
        log.info("异常状态 from '" + from + "' to '" + to + "' on event '" + event +
                "' with context '" + context + "'.");
    }

    public static void main(String[] args) {
        // 构建状态机转换Builder
        StateMachineBuilder<MyAnnotationStateMachine, String, String, Integer> builder
                = StateMachineBuilderFactory.create(MyAnnotationStateMachine.class, String.class,
                String.class, Integer.class);
        builder.setStateMachineConfiguration(StateMachineConfiguration.create().enableDebugMode(false));

        //Use State Machine
        MyAnnotationStateMachine fsm = builder.newStateMachine("A");
        fsm.fire("GoToB", 10);
        fsm.fire("GoToC", 10);
        System.out.println("Current state is " + fsm.getCurrentState());
    }
}
